#include <stdio.h>
#include <stdlib.h>
#include <windows.h> 

char buf[1 * 1024];
char *pc;
int *pi;
unsigned int offset = 0;
long width;
long heigth;
int biwidth, biheigth;
unsigned char rgb[2000][2000 * 3];

//struct tagBITMAPFILEHEADER{
//     WORD    bfType; //文件类型，必须是0x424D，即字符串“BM”
//     DWORD   bfSize; //指定文件大小，包括这14个字节
//     WORD    bfReserved1; //保留字，不用考虑
//     WORD    bfReserved2; //保留字，不用考虑
//     DWORD   bfOffBits; //从文件头到实际位图数据的偏移字节数
//} header;

//typedef struct tagBITMAPINFOHEADER{
// DWORD  biSize; //该结构的长度，为40
// LONG      biWidth; // 图像的宽度，单位是像素
// LONG      biHeight; // 图像的高度，单位是像素
// WORD      biPlanes; // 位平面数，必须是1，不用考虑
// WORD      biBitCount; // 指定颜色位数，1为二值，4为16色，8为256色，16、24、32为真彩色 DWORD     biCompression; / 指定是否压缩，有效的值为BI_RGB，BI_RLE8，BI_RLE4,BI_BITFIELDS
// DWORD     biSizeImage; // 实际的位图数据占用的字节数
// LONG      biXPelsPerMeter; // 目标设备水平分辨率，单位是每米的像素数
// LONG      biYPelsPerMeter; // 目标设备垂直分辨率，单位是每米的像素数
// DWORD     biClrUsed; //实际使用的颜色数，若该值为0，则使用颜色数为2的bitBitCount次方种
// DWORD     biClrImportant; //图像中重要的颜色数，若该值为0，则所有的颜色都是重要的
//} BITMAPINFOHEADER;
//
// typedef struct tagRGBQUAD
//{
// BYTE rgbBlue; //该颜色的蓝色分量
// BYTE rgbGreen; //该颜色的绿色分量
//    BYTE rgbRed; //该颜色的红色分量
//    BYTE rgbReserved; //保留值
//} RGBQUAD;

int main(int argc, char *argv[])
{

    unsigned char *fp_temp;
    FILE *fpbmp;
    FILE *fpput;
    int i, hc;

    printf("sizeof(DWORD) = %d  sizeof(int) = %d\n", sizeof(DWORD), sizeof(int));
    printf("sizeof(long) = %d  sizeof(long) = %d\n", sizeof(long), sizeof(long));

    fpbmp = fopen("a.bmp", "rb+");

    if (fpbmp == NULL)
    {
        printf("FOPEN ERR!\n");
        getchar();
        exit(0);
    }

    offset = fread(&header, 1, sizeof(BITMAPFILEHEADER), fpbmp);
    printf("########################## offset=%d ##########################\n", offset);

    pc = (char *)(&header.bfType);
    printf("header.bfType = %c%c\n", pc[0], pc[1]);

    pi = (int *)(&header.bfSize);
    printf("header.bfSize = %d\n", *pi);

    pi = (int *)(&header.bfOffBits);
    printf("header.bfOffBits = %d\n", *pi);

    offset += fread(&infoheader, 1, sizeof(BITMAPINFOHEADER), fpbmp);
    printf("########################## offset=%d ##########################\n", offset);

    pc = (char *)(&infoheader.biSize);
    printf("infoheader.biSize = %d\n", pc[0] + pc[1] * 256);

    biwidth = infoheader.biWidth;
    biheigth = infoheader.biHeight;
    printf("infoheader.biWidth = %d\n", biwidth);
    printf("infoheader.biHeight = %d\n", biheigth);

    pc = (char *)(&infoheader.biPlanes);
    printf("infoheader.biPlanes = %d\n", pc[0] + pc[1] * 256);

    pc = (char *)(&infoheader.biBitCount);
    printf("infoheader.biBitCount = %d\n", pc[0] + pc[1] * 256);

    pc = (char *)(&infoheader.biCompression);
    printf("infoheader.biCompression = %d\n", pc[0] + pc[1] * 256);

    pc = (char *)(&infoheader.biSizeImage);
    printf("infoheader.biSizeImage = %d_%d_%d_%d\n", pc[0], pc[1], pc[2], pc[3]);

    printf("infoheader.biXPelsPerMeter = %d\n", infoheader.biXPelsPerMeter);
    printf("infoheader.biYPelsPerMeter = %d\n", infoheader.biYPelsPerMeter);

    pc = (char *)(&infoheader.biClrUsed);
    printf("infoheader.biClrUsed = %d\n", pc[0] + pc[1] * 256);

    pc = (char *)(&infoheader.biClrImportant);
    printf("infoheader.biClrImportant = %d\n", pc[0] + pc[1] * 256);

    hc = biwidth * 3;
    while ((hc % 4) != 0)
    {
        hc++;
    }

    for (i = 0; i < biheigth; i++)
    {
        fread(rgb[i], 1, hc, fpbmp);
    }

    return 0;
}